package com.netty.test.service;

import com.netty.test.bean.HttpResult;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.*;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.hserver.core.interfaces.HttpRequest;
import top.hserver.core.ioc.annotation.Bean;
import top.hserver.core.server.context.ConstConfig;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @author hxm
 */

@Bean
public class DispatcherOkHttpService {

    private static final Logger log = LoggerFactory.getLogger(DispatcherOkHttpService.class);

    private static OkHttpClient client = new OkHttpClient();

    private static final String CONTENTTYPE = "content-type";

    public HttpResult request(String url, HttpRequest httpRequest) {
        try {
            Request.Builder connection = new Request.Builder()
                    .url(url);
            httpRequest.getHeaders().forEach((k, v) -> {
                if (!"Content-Type".equalsIgnoreCase(k) && !"Content-length".equalsIgnoreCase(k)) {
                    connection.addHeader(k, v);
                }
            });
            String header = httpRequest.getHeader("Content-Type");
            RequestBody requestBody=null;
            if (header != null) {
                //表单
                if (header.contains("x-www-form")) {
                    FormBody.Builder builder = new FormBody.Builder();
                    httpRequest.getRequestParams().forEach(builder::add);
                    requestBody=builder.build();
                } else if (header.contains("multipart")) {
                    MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                    //存在文件上传的
                    if (httpRequest.getMultipartFile().size() > 0) {
                        httpRequest.getMultipartFile().forEach((k, v) -> {
                            RequestBody rb = RequestBody.create(MediaType.parse(header), v.getFile());
                            builder.addFormDataPart(k, v.getFileName(),rb);
                        });
                    }
                    httpRequest.getRequestParams().forEach(builder::addFormDataPart);
                    requestBody = builder.build();
                } else {
                    if (httpRequest.getRawData()!=null){
                        requestBody = RequestBody.create(MediaType.parse(header), httpRequest.getRawData());
                    }
                }
            }
            Request build = connection.method(httpRequest.getRequestType().name(), requestBody).build();
            Response execute = client.newCall(build).execute();
            HttpResult httpResult = getHttpResult(execute);
            assert execute.body() != null;
            httpResult.setContent(execute.body().bytes());
            return httpResult;
        } catch (IOException e1) {
            e1.printStackTrace();
            log.error(e1.getMessage());
        }
        return null;
    }


    private HttpResult getHttpResult(Response response) {
        HttpResult httpResult = new HttpResult();
        //处理响应类型
        if (response.code() == HttpResponseStatus.OK.code()) {
            if (Objects.requireNonNull(response.header(CONTENTTYPE)).contains("application/json")) {
                httpResult.setRespType(HttpResult.RespType.JSON类型);
            } else if (Objects.requireNonNull(response.header(CONTENTTYPE)).contains("text/plain")) {
                httpResult.setRespType(HttpResult.RespType.文本类型);
            } else if (Objects.requireNonNull(response.header(CONTENTTYPE)).contains("text/html")) {
                httpResult.setRespType(HttpResult.RespType.HTML类型);
            } else {
                httpResult.setHttpStatus(HttpResponseStatus.valueOf(response.code()));
                httpResult.setRespType(HttpResult.RespType.未知类型);
            }
        } else if (response.code() == HttpResponseStatus.FOUND.code() || response.code() == HttpResponseStatus.MOVED_PERMANENTLY.code()) {
            httpResult.setRespType(HttpResult.RespType.重定向类型);
            httpResult.setLocation(response.header("location"));
        } else {
            httpResult.setHttpStatus(HttpResponseStatus.valueOf(response.code()));
            httpResult.setRespType(HttpResult.RespType.未知类型);
        }
        Headers headers = response.headers();
        Map<String, List<String>> heads = headers.toMultimap();
        Map<String, String> header=new HashMap<>(1);
        heads.forEach((k,v)->{
            if (!k.equalsIgnoreCase("transfer-encoding")) {
                header.put(k, v.size() > 0 ? v.get(0) : "");
            }
        });
        httpResult.setHeaders(header);
        return httpResult;
    }


    public FullHttpResponse getFullHttpResponse(HttpResult httpResult) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1,
                httpResult.getHttpStatus(),
                Unpooled.wrappedBuffer(httpResult.getContent()));
        response.headers().set("HServer", ConstConfig.VERSION);
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
        httpResult.getHeaders().forEach((k, v) -> response.headers().set(k, v));
        response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
        return response;
    }


}
